package com.csea;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Csea
 * @title
 * @date 2019/12/12 21:42
 */
public class Test4 {
    public static void main(String[] args) {
        List<Integer> list1 = new ArrayList<>();
        for (int i = 0; i < 1000; i++) {
            list1.add(i);
        }

        // 串行stream
        List<Integer> list2 = new ArrayList<>();
        list1.stream().forEach(x -> list2.add(x));
        System.out.println(list1.size());
        System.out.println(list2.size());
        // 并行stream
        List<Integer> list3 = new ArrayList<>();
        list1.parallelStream().forEach(x -> list3.add(x));
        System.out.println(list3.size());

        /**
         * 并行会数据丢失，因为当前操作的线程集合并不是安全的，所以多个线程访问共享数据出现了冲突，
         * 这个在redis中也有存在（特别是秒杀系统），可以添加redis分布式锁解决
         * 在官方的文档中说明：由于并行stream中使用Collections本身就不是线程安全，所以会由于多线程情况下导致数据不一致
         * Collections有提供自身的线程同步块，但是使用这些线程同步块可能存在线程竞争的问题
         * 如果想避免线程竞争的问题   operations和parallelStream能够让我们得到一个 在非线程安全的情况下 数据处理过程
         *  这个前提是 我们在操作的过程中，对于非线程安全中的数据不能修改
         */
        //解决list.parallelStream()并行流线程安全的方式：
        // 自定义编码，添加线程锁的方式，或者stream API中的线程安全的终端安全操作完成执行过程
        List<Integer> list4 = list1.parallelStream().collect(Collectors.toList());
    }
}
